package cn.qingyun.gis.modules.enterprise.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import cn.qingyun.gis.exception.AuthErrorException;
import cn.qingyun.gis.exception.CommonException;
import cn.qingyun.gis.modules.enterprise.config.ManagerType;
import cn.qingyun.gis.modules.enterprise.entity.Grid;
import cn.qingyun.gis.modules.enterprise.entity.Permissions;
import cn.qingyun.gis.modules.enterprise.mapper.PermissionsMapper;
import cn.qingyun.gis.modules.enterprise.service.IGridService;
import cn.qingyun.gis.modules.enterprise.service.IPermissionsService;
import cn.qingyun.gis.modules.init.system.constant.CommonMessage;
import cn.qingyun.gis.modules.init.system.vo.LoginUser;
import cn.qingyun.gis.modules.init.utils.SystemUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 * 业务权限表 服务实现类
 * </p>
 *
 * @author skb
 * @since 2024-04-17
 */
@Service
@Slf4j
public class PermissionsServiceImpl extends ServiceImpl<PermissionsMapper, Permissions> implements IPermissionsService {

    @Autowired
    private IGridService iGridService;

    @Value("${qingyun.grid.url:http://127.0.0.1}")
    private String hwGridHost; // 华为-网格内网测试地址

    private static final Integer RES_CODE_SUCCESS = 0;

    @Override
    public void syncPermissions(List<Permissions> list, String phone, String crmAccount) {
        // 先删除
        QueryWrapper<Permissions> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Permissions::getCrmAccount, crmAccount);
        this.remove(queryWrapper);
        //再新增
        list.forEach(item -> item.setPhone(phone).setCrmAccount(crmAccount).setManagerType(ManagerType.calcManagerType(item.getAllParentCode())).setIsMeltGrid(true).setCreateTime(new Date()).setUpdateTime(new Date()));
        this.saveBatch(list);
    }

    @Override
    public Permissions isValidCrmAccount(String crmAccount) {
        QueryWrapper<Permissions> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Permissions::getCrmAccount, crmAccount).orderByAsc(Permissions::getManagerType)
                .last("LIMIT 1");

        Permissions channelPermission = this.baseMapper.selectOne(queryWrapper);
        if (Objects.isNull(channelPermission)) {
            throw new AuthErrorException("用户权限未配置，请联系管理员");
        }

        return channelPermission;
    }

    @Override
    public void addOrUpdate(Permissions channelPermissions) {
        try {
            QueryWrapper<Grid> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().select(Grid::getName).eq(Grid::getCode, channelPermissions.getAreaCode()).last("limit 1");
            Grid channelGrid = iGridService.getOne(queryWrapper);
            String fullCode = this.getFullCode(channelPermissions.getAreaCode());
            String fullName = this.getFullName(channelPermissions.getAreaCode());
            channelPermissions.setAreaName(channelGrid.getName()).setAllParentCode(fullCode).setFullName(fullName);
            this.saveOrUpdate(channelPermissions);
        } catch (Exception e) {
            throw new CommonException("操作业务权限失败");
        }
    }

    /**
     * @description: 递归获取名称
     * @author skb
     * @date 2023/12/11 17:46
     */
    public String getFullName(String code) {
        QueryWrapper<Grid> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().select(Grid::getName, Grid::getLevel, Grid::getParentCode).eq(Grid::getCode, code);
        Grid channelGrid = iGridService.getOne(queryWrapper);
        if (channelGrid == null) {
            return "";
        }
        if ("4".equals(channelGrid.getLevel())) {
            String name = "";
            if (channelGrid.getName().contains("-")) {
                name = channelGrid.getName().split("-")[1];
            } else {
                name = channelGrid.getName();
            }
            channelGrid.setName(name);
        }
        if ("0".equals(channelGrid.getParentCode())) {
            return channelGrid.getName();
        }
        String parentName = getFullName(channelGrid.getParentCode());
        return parentName.isEmpty() ? channelGrid.getName() : parentName + "-" + channelGrid.getName();
    }

    /**
     * @description: 递归获取网格
     * @author skb
     * @date 2024/1/4 9:39
     */
    public String getFullCode(String code) {
        QueryWrapper<Grid> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().select(Grid::getCode, Grid::getLevel, Grid::getParentCode).eq(Grid::getCode, code);
        Grid channelGrid = iGridService.getOne(queryWrapper);
        if (channelGrid == null) {
            return "";
        }
        if ("0".equals(channelGrid.getParentCode())) {
            return channelGrid.getCode();
        }
        String parentCode = getFullCode(channelGrid.getParentCode());
        return parentCode.isEmpty() ? channelGrid.getCode() : parentCode + "," + channelGrid.getCode();
    }

    /**
     * @description: 验证工号是否重复
     * @author skb
     * @date 2024/2/2 10:43
     */
    public boolean validCrmAccount(String crmAccount) {
        QueryWrapper<Permissions> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Permissions::getCrmAccount, crmAccount).eq(Permissions::getIsMeltGrid,true);
        List<Permissions> list = this.list(queryWrapper);
        if (CollectionUtil.isEmpty(list)) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * @description: 获取网格权限数据
     * @author skb
     * @date 2023/12/20 15:03
     */
    public List<Permissions> getPermissions() {
        LoginUser currentUser = SystemUtil.getCurrentUser();
        if (ObjectUtil.isNull(currentUser)) {
            throw new CommonException(CommonMessage.GET_USER_FAILED);
        }
        QueryWrapper<Permissions> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Permissions::getCrmAccount, currentUser.getWorkNo()).or(wrapper -> wrapper.eq(Permissions::getPhone, currentUser.getPhone()));
        List<Permissions> list = this.list(queryWrapper);
        if (Objects.isNull(list) || list.isEmpty()) {
            throw new CommonException("获取人员权限失败");
        }
        return list;
    }


    @Override
    public List<Permissions> getGridByAccount(String crmAccount) {
        List<Permissions> authItems = Lists.newArrayList();
        try {
            Map<String, Object> params = Maps.newHashMap();
            params.put("type", 3);
            params.put("crmAccount", crmAccount);
            HttpRequest httpRequest = HttpUtil.createPost(hwGridHost).body(JSONUtil.toJsonStr(params))
                    .header("Content-Type", "application/json");
            HttpResponse response = httpRequest.execute();
            if (response.isOk()) {
                log.info("获取权限网格 {} 参数 {} 结果 {}", hwGridHost, params, response.body());
                cn.hutool.json.JSONObject parseObj = JSONUtil.parseObj(response.body());
                if (RES_CODE_SUCCESS.equals(parseObj.getByPath("res_code", Integer.class))) {
                    for (Object o : parseObj.getJSONArray("result")) {
                        cn.hutool.json.JSONObject entries = (cn.hutool.json.JSONObject) o;
                        authItems.add(entries.toBean(Permissions.class));
                    }
                }
                if (CollUtil.isEmpty(authItems)) {
                    throw new CommonException("根据工号获取权限网格失败, 请联系管理员");
                }
            }
            // 去重逻辑
            Map<String, Permissions> uniqMap = Maps.newHashMap();
            for (Permissions authItem : authItems) {
                uniqMap.put(authItem.getAreaCode(), authItem);
            }
            return new ArrayList<>(uniqMap.values());
        } catch (Exception e) {
            log.error("根据工号获取权限网格失败, 请联系管理员", e);
            throw new CommonException("根据工号获取权限网格失败, 请联系管理员");
        }
    }

}
